//定义页面管理对象
//注：page格式可参考pages/cs.js
var CmdPage = {
    pages: [], //页面
    menus: new Map(), //一级菜单
    //用于取出类似“ISNAME<n+2>:”中的2
    regExp_nIndex: new RegExp("([\\w\\d_]+)(<n\\+([\\d])>)(.*)$"),
    //添加页面
    //page:页面参数定义对象
    add: function (page) {
        for (let i = 0; i < this.pages.length; i++) {
            if (eval(this.pages[i].title) == eval(page.title)) {
                alert("检测到菜单名[" + eval(page.title) + "]重复,请修改!");
                return;
            }
        }
        //放入数组列表
        this.pages.push(page);
        //添加为菜单map中的项
        this.menus.set(page.menu, page.menu);
        //定义了init方法，则执行
        if (defined(page.init)) {
            page.init();
        }
        //创建表格的空数据（如果有）
        this.createPageDgEmptyData(page);
    },
    //根据标题获得page
    //title:tabs的title
    getPageByTitle: function (title) {
        if (title == null) return null;
        for (let i in this.pages) {
            if (eval(this.pages[i].title) == title) {
                return this.pages[i];
            }
        }
        return null;
    },
    //给控件添加title提示
    //element：控件
    //obj:如果有title属性或者cmdKey属性就添加为title，否则不添加
    addTitleTip: function (element, obj) {
        if (!element || !obj) return;
        if (defined(obj.title)) {
            element.attr("title", obj.title);
        } else if (defined(obj.cmdKey)) {
            element.attr("title", obj.cmdKey);
        }
    },
    //为控件添加属性
    //element:控件
    //attrs:属性数组
    addAttrsToElement: function (element, attrs) {
        if (!element || !attrs) return;
        for (var key in attrs) {
            element.attr(key, attrs[key]);
        }
    },
    //生成刷新和保存按钮数据
    createfreshAndSaveEl: function (page) {
        if (notNullOrFalse(page.refreshBtnCmd) || notNullOrFalse(page.saveBtn)) {
            var div = $("<div></div>");
            div.addClass("page_header"); //样式
            //刷新按钮
            if (notNullOrFalse(page.refreshBtnCmd)) {
                var btn = $("<button></button>");
                btn.attr("id", page.id + "_refresh"); //id
                btn.attr("page", page.id); //记录页面id,方便刷新
                // btn.click(RefreshClick);//绑定事件(不成功？)
                btn.attr("onclick", "refreshClick(this);");
                btn.attr("cmd", page.refreshBtnCmd); //绑定指令
                btn.attr("title", page.refreshBtnCmd); //提示文字
                btn.text(i18n.lan.common.refresh); //按钮文字
                div.append(btn);
            }
            //保存按钮
            if (notNullOrFalse(page.saveBtn)) {
                var btn = $("<button></button>");
                btn.attr("onclick", "CmdPage.savePageCmd(this)");
                btn.text(i18n.lan.common.save);
                btn.attr("page", page.id);
                btn.attr("id", page.id + "_save");
                div.append(btn);
            }
            return div;
        }
        return null;
    },
    //创建label
    //parent表示生成的控件的父控件
    //el表示控件的参数定义对象,必须要有text
    createLabel: function (parent, el) {
        if (!parent || !(el && el.text)) return;
        let label = $("<label></label>");
        label.attr("class", "label");
        label.text(el.text);
        this.addAttrsToElement(label, el.attrs);
        parent.append(label);
        return label;
    },
    //创建input type=text,label表示在前面添加说明文字
    //parent表示生成的控件的父控件
    //el表示控件的参数定义对象
    createInputText: function (parent, el) {
        this.createLabel(parent, { text: el.label });
        //text
        var text = $('<input type="text"></input>');
        this.addTitleTip(text, el.attrs);
        parent.append(text);
        return text;
    },
    //创建input type=checkbox
    //parent表示生成的控件的父控件
    //el表示控件的参数定义对象
    //如果el定义了label，则在后面添加说明文字
    createInputCheckbox: function (parent, el) {
        //格式检查
        //有label无id会提示错误
        if (defined(el.label) && !defined(el.id)) {
            alert("Checkbox has lable, but no id!");
            return;
        }
        //生成控件
        let checkbox = $('<input type="checkbox"></input>');
        if (defined(el.id)) {
            checkbox.attr("id", el.id);
        }
        parent.append(checkbox);
        //label
        let label = this.createLabel(parent, {
            text: el.label,
            attrs: { for: el.id },
        });
        this.addTitleTip(label, el.attrs);
        return checkbox;
    },
    //创建easyui combobox
    //parent表示生成的控件的父控件
    //el表示控件的参数定义对象
    createEasyuiCombobox: function (parent, el) {
        //检测必须有的项(id,items)
        if (!el.id || !el.items) {
            alert("Combobox no id or items!");
            return;
        }
        //items需要将对象加引号变为string
        if (typeof el.items != "string") {
            alert("Combobox items must be string, eg:'your object'");
            return;
        }
        //label
        let label = this.createLabel(parent, { text: el.label });
        this.addTitleTip(label, el.attrs);
        //生成对象
        let combobox = $('<input id="{id}" editable="false">'.format(el));
        this.addTitleTip(combobox, el.attrs);
        //属性转化
        //dumpKey（如果未定义dealDumpParam,则生成默认刷新值的方法）
        if (el.attrs && el.attrs.dumpKey && !el.dealDumpParam) {
            //$('#id').combobox('setValue', '0');
            el.attrs.dealDumpParam = "$('#{id}').combobox('setValue',value)".format(
                el
            );
        }
        //cmdKey转换(如果未定义getValue,则生成默认获得值的方法)
        if (el.attrs && el.attrs.cmdKey && !el.getValue) {
            //$('#id').combobox('getValue');
            el.attrs.getValue = "$('#{id}').combobox('getValue')".format(el);
        }
        //属性转化end
        this.addAttrsToElement(combobox, el.attrs);
        parent.append(combobox);
        //添加easyui生成combobox的js代码
        let script = "<script>";
        script +=
            '$("#' +
            el.id +
            '").combobox({data:' +
            el.items +
            ',valueField:"value",textField:"text"});';
        //默认选中0的值
        script += '$("#{0}").combobox("setValue",{1})'.format(
            el.id,
            el.items + "[0].value"
        );
        script += "</script>";
        //将script附加到父元素中
        parent.html(parent.html() + script);
        return combobox;
    },
    //创建table
    //parent表示生成的控件的父控件
    //el表示控件的参数定义对象
    //TODO:使用时请测试
    createTable: function (parent, el) {
        //检查必要属性
        if (!el.columns || !el.rowCount) {
            alert("Table must has columns and rowCount!");
            return;
        }
        //创建控件
        let table = $('<table class="table"></table>');
        var tr = $('<tr class="head"></tr>'); //标题行
        var tr2 = $("<tr></tr>");
        let columns = el.columns;
        //列
        for (var j = 0; j < columns.length; j++) {
            var columnTitle = columns[j].columnTitle;
            columnTitle = eval(
                columnTitle.startsWith("i18n.lan.") ?
                    columnTitle :
                    "i18n.lan." + page.id + "." + columns[j].columnTitle
            );
            tr.append($("<th>" + columnTitle + "</th>"));
            var td = $("<td></td>");
            var tdChild = null; //td内部内容
            if (defined(columns[j].columnType)) {
                //有列类型
                if (columns[j].columnType == "checkbox") {
                    tdChild = $('<input type="checkbox"></input>');
                    td.append(tdChild);
                    td.css("text-align", "center");
                } else if (
                    columns[j].columnType == "select" &&
                    defined(columns[j].items)
                ) {
                    tdChild = $("<select></select>");
                    var items = eval(columns[j].items);
                    for (var itemIndex in items) {
                        tdChild.append(
                            '<option value="' + i + '">' + items[itemIndex] + "</option>"
                        );
                    }
                    td.append(tdChild);
                }
            }
            //要设置属性的控件(如果有子控件就是子控件，否则就是td)
            var propEl = tdChild == null ? td : tdChild;
            //控件属性
            for (var key in columns[j]) {
                if (key != "columnTitle") {
                    propEl.attr(key, columns[j][key]);
                }
                if (key == "cmdKey") {
                    propEl.attr("title", columns[j][key]);
                }
            }
            tr2.append(td);
        }
        talbe.append(tr); //标题部分
        //行
        var rowCount = eval(el.rowCount);
        for (var j = 0; j < rowCount; j++) {
            if (columns[0].columnTitle == "i18n.lan.common.index") {
                //序号列
                tr2.children("td").eq(0).text(j); //第1列修改为序号
            }
            talbe.append(tr2.prop("outerHTML").replaceAll("<n>", j)); //加入表格
        }
        let tableParent = $('<div class="tableParent"></div>');
        tableParent.append(talbe);
        tableParent.attr("onscroll", "FixTabelHead(this)"); //固定表头
        parent.append(tableParent);
        return table;
    },
    //创建easyui的datagird
    createEasyuiDatagrid: function (parent, el) {
        //加一个父盒子防止出现滚动条的情况
        let dgParent = $("<div class='dgParent'></div>");
        //生成datagrid要使用的相关属性
        let dg = {};
        //datagrid的id
        dg.id = el.id;
        //datagrid定义的data和行数据
        dg.data = el.dataVarStr;
        dg.rowData = el.rowDataVarStr;
        //将生成的html添加到表格父级div中
        dgParent.html(DatagridTool.createHtml(dg));
        //将datagrid div加入page div
        parent.append(dgParent);
        //其它数据，页面控件显示时才会使用，可以放在后面
        //1.如果没有头部tilte根据field生成
        let column;
        for (var col in el.data.columns[0]) {
            column = el.data.columns[0][col];
            if (!defined(column.title) && defined(column.field)) {
                //title=从页面的资源文件中找filed,如果没找到在公共资源中找field
                column.title = this.getPageLanVal(el.pageId, column.field);
            }
        }
        //1.end
        //2.默认事件和属性
        if (!defined(el.data.singleSelect)) {
            el.data.singleSelect = true;
        }
        if (!defined(el.data.onDblClickCell)) {
            // el.data.onDblClickCell = DatagridTool.onDblClickCell;
            el.data.onDblClickCell = DatagridTool.onDblClickCell;
        }
        if (!defined(el.data.onClickCell)) {
            // el.data.onClickCell = DatagridTool.endEditing;
            el.data.onClickCell = DatagridTool.onDblClickCell;
        }
        if (!defined(el.data.onEndEdit)) {
            el.data.onEndEdit = DatagridTool.onEndEdit;
        }
        //2.end
    },
    //创建页面body内容
    createBody: function (page) {
        //页面div
        var div = $('<div class="page"></div>');
        div.attr("id", page.id);
        //刷新和保存按钮
        var freshAndSaveDiv = this.createfreshAndSaveEl(page);
        if (freshAndSaveDiv) div.append(freshAndSaveDiv);
        //用户控件
        for (var i = 0; i < page.el.length; i++) {
            var el;
            //<input type=text>
            if (page.el[i].elname == "text") {
                el = this.createInputText(div, page.el[i]);
            }
            //<input type=checkbox>
            else if (page.el[i].elname == "checkbox") {
                el = this.createInputCheckbox(div, page.el[i]);
            } else if (page.el[i].elname == "combobox") {
                el = this.createEasyuiCombobox(div, page.el[i]);
            }
            // table
            else if (page.el[i].elname == "table") {
                this.createTable(div, page.el[i]);
            }
            //easyui datagrid控件
            else if (page.el[i].elname == "datagrid") {
                //为datagrid自动添加一个id
                page.el[i].id = page.id + "_dg";
                //添加pageId
                page.el[i].pageId = page.id;
                //easyui使用js生成datagrid的data,需要字符串而不是对象
                page.el[i].dataVarStr = page.id + ".el[{0}].data".format(i);
                //easyui loadData的数据，需要字符串而不是对象
                page.el[i].rowDataVarStr = page.id + ".dgData";
                //datagrid表格默认自动换一行
                page.el[i].endRow = true;
                this.createEasyuiDatagrid(div, page.el[i]);
            }
            //其它控件
            else {
                //标签内部内容
                let text = defined(page.el[i].text) ? page.el[i].text : "";
                //生成标签
                el = $("<{0}>{1}</{0}>".format(page.el[i].elname, text));
                div.append(el);
            }
            //为控件添加属性
            for (var key in page.el[i].attrs) {
                if (el) {
                    el.attr(key, page.el[i].attrs[key]);
                }
            }
            //换一行
            if (page.el[i].endRow) div.append('<div class="split"></div>');
        }
        return div.prop("outerHTML");
    },
    //创建页面datagrid空数据
    createPageDgEmptyData: function (page) {
        for (let i in page.el) {
            if (page.el[i].elname == "datagrid") {
                let rowCount = page.el[i].rowCount;
                page.dgData = {
                    rows: [],
                    columns: page.el[i].data.columns[0],
                };
                for (let row = 0; row < rowCount; row++) {
                    page.dgData.rows.push({});
                    for (let col in page.el[i].data.columns[0]) {
                        page.dgData.rows[row][page.el[i].data.columns[0][col].field] = "";
                    }
                    page.dgData.rows[row].index = row;
                }
            }
        }
    },
    //从刷新的数据中更新页面;
    //pages:page的数组;
    //dumpData:刷新出的数据map;
    updatePageByDumpData: function (pages, dumpData) {
        var key, value;
        //遍历控件
        $("[dumpKey]").each(function () {
            key = $(this).attr("dumpKey");
            //记录的刷新数据中有值
            if (dumpData.has(key)) {
                value = dumpData.get(key);
                if ($(this).attr("dumpParamIndex")) {
                    //多个参数需要分隔的
                    value = CmdPage.getDumpDataByIndex(
                        value,
                        $(this).attr("dumpParamIndex")
                    );
                }
                //定义了处理参数的方法
                if ($(this).attr("dealDumpParam")) {
                    value = eval($(this).attr("dealDumpParam"));
                }
                CmdPage.setElementValue(this, value);
            }
        });
        if (pages) {
            for (let i in pages) {
                CmdPage.updatePageDatagridByDump(pages[i], dumpData);
            }
        }
    },
    // 更新dumpKey或cmdKey中的<n>或<n+整数>为序号
    updateCmdNum2Index: function (strKey, index) {
        if (strKey.indexOf("<n>") != -1) {
            return strKey = strKey.replace("<n>", index);
        } else if (strKey.indexOf("<n+") != -1) {
            // 如果n为1时，将类似“ISNAME<n+2>:”转为ISNAME3:
            if (this.regExp_nIndex.test(strKey)) {
                let results = this.regExp_nIndex.exec(strKey);
                return strKey.replace(results[2], (index + parseInt(results[3])).toString());
            }
        }
    },
    //从刷新数据中更新页面中的表格
    updatePageDatagridByDump: function (page, dumpData) {
        if (!page) return;
        if (defined(eval(page.id + ".dgData"))) {
            //有表格数据
            let dgData = eval(page.id).dgData;
            let rows = dgData.rows;
            let columns = dgData.columns;
            let val;
            for (let col in columns) {
                if (columns[col].dumpKey) {
                    //有dumpKey
                    let dumpKey;
                    for (let row in rows) {
                        dumpKey = this.updateCmdNum2Index(columns[col].dumpKey, parseInt(row));
                        if (dumpData.has(dumpKey)) {
                            val = dumpData.get(dumpKey);
                            //刷新数据是多个参数，根据index取出
                            if (defined(columns[col].dumpParamIndex)) {
                                val = this.getDumpDataByIndex(val, columns[col].dumpParamIndex);
                            }
                            //参数值需要转码
                            if (defined(columns[col].transcode)) {
                                val = Device.transCodeToChar(val);
                            }
                            //定义了自己处理参数的方法
                            if (defined(columns[col].dealDumpParam)) {
                                let value = val; //用于下面的自定义方法
                                val = eval(columns[col].dealDumpParam);
                            }
                            dgData.rows[row][columns[parseInt(col)].field] = val;
                        }
                    }
                }
            }
            DatagridTool.updateData(page.id + "_dg");
        }
    },
    // 设置刷新控件的值
    setElementValue: function (element, value) {
        $(element).attr("dumpVal", value); //记录值，方便判断是否修改
        var type = element.type;
        // taSend.append(element+","+type+"\n");
        if ($(element).attr("transcode") == "true") {
            value = Device.transCodeToChar(value + "");
        }
        if (type == "checkbox") {
            //复选框
            element.checked = value == "1";
        } else if (type == "text" || type == "textarea") {
            //输入框
            $(element).val(value);
        } else if (type == "select-one") {
            if (element.length > parseInt(value)) {
                //有可选择的序号
                element.selectedIndex = parseInt(value);
            } else {
                element.selectedIndex = element.length - 1;
            }
        } else {
            $(element).text(value);
        }
    },
    //获得刷新参数中的部分; value参数值;index为逗号分隔后的序号
    getDumpDataByIndex: function (value, dumpParamIndex) {
        //如果其中一个无效，则返回
        if (!value || !defined(dumpParamIndex)) {
            return value;
        }
        //根据序号取出参数
        var vals = value.split(",");
        dumpParamIndex = parseInt(dumpParamIndex);
        if (vals.length > dumpParamIndex) {
            //序号有效
            value = vals[dumpParamIndex];
        }
        return value;
    },
    //获得控件的值
    getElementValue: function (element) {
        var type = element.type;
        var value;
        if (type == "checkbox") {
            //复选框
            value = element.checked ? "1" : "0";
        } else if (type == "text" || type == "textarea") {
            //输入框
            value = $(element).val();
        } else if (type == "select-one") {
            //下拉框
            value = $(element)[0].selectedIndex;
        } else {
            value = $(element).text();
        }
        if (defined($(element).attr("transcode"))) {
            //要求转码
            value = Device.transCode(value);
        }
        return value;
    },
    //获得页面语言值
    getPageLanVal: function (pageId, key) {
        //从页面对象中找
        let val = i18n.getKeyVal(pageId, key);
        //如果不存在则从通用数据中找
        if (typeof val == "undefined") {
            val = i18n.getKeyVal("common", key);
        }
        //如果不存在则返回空串
        if (typeof val == "undefined") {
            val = "";
        }
        return val;
    },
    //获得刷新指令,返回一个数组
    getRefreshCmds: function (pageId) {
        var btnId = "#" + pageId + "_refresh";
        return $(btnId).attr("cmd").split(",");
    },
    //页面保存按钮功能
    savePageCmd: function (saveBtn) {
        var pageId = $(saveBtn).attr("page");
        var cmds = [];
        DatagridTool.endEditing();
        cmds.push("STARTCMD"); //开始设置的指令(加快速度)
        $("#" + pageId + " [cmdKey]").each(function () {
            let cmdKey = $(this).attr("cmdKey"); //指令头部
            let value;
            if (defined($(this).attr("getValue"))) {
                //有获得指令的方法时
                value = eval($(this).attr("getValue"));
            }
            //其它，从控件中获得值
            else {
                value = CmdPage.getElementValue(this);
            }
            //   如果没有值替换标记<v>，则添加到最后
            if (cmdKey.indexOf("<v>") == -1) {
                cmds.push(cmdKey + value);
            } else {
                //   有值替换标记，则替换
                cmds.push(cmdKey.replace("<v>", value));
            }
        });
        //有表格
        if (eval(pageId + ".dgData")) {
            let dgData = eval(pageId + ".dgData");
            let rows = $("#" + pageId + "_dg").datagrid("getChanges"); //dgData.rows;
            let columns = dgData.columns;
            let val, val2; //值
            let transcode;
            for (let col in columns) {
                //查找有cmdKey的列
                if (defined(columns[col].cmdKey)) {
                    let cmdKey;
                    for (let row in rows) {
                        //生成指令
                        // cmdKey = columns[col].cmdKey.replace("<n>", rows[row].index); //替换指令头中的序号
                        cmdKey = this.updateCmdNum2Index(columns[col].cmdKey, rows[row].index);
                        val = rows[row][columns[col].field];
                        //需要转码
                        transcode = defined(columns[col].transcode);
                        if (transcode) {
                            val = Device.transCode(val);
                        }
                        //设置指令包括多个参数
                        if (defined(columns[col].otherFields)) {
                            val2 = "";
                            let otherFields = columns[col].otherFields.split(",");
                            //循环其它参数（注意：转码使用的同一个(cmdKey这一列的transcode)）
                            for (let fieldIndex in otherFields) {
                                val2 = rows[row][otherFields[fieldIndex]];
                                val2 = transcode ? Device.transCode(val2) : val2;
                                val += "," + val2;
                            }
                        }
                        //自定义了获得指令的方法
                        if (defined(columns[col].getValue)) {
                            let value = val; //下面getValue方法使用
                            //使用序号时需要使用rows[row].index
                            val = eval(columns[col].getValue);
                        }
                        cmds.push(cmdKey + val); //获得行中的列的值，并放入保存的指令集
                    }
                }
            }
        }
        cmds.push("COMMITCMD"); //指令提交
        cmds = cmds.concat(this.getRefreshCmds(pageId)); //添加刷新指令
        this.clearPageData(eval(pageId));
        sendCmds(cmds);
    },
    //获得checkbox的值(cmdKey="cmd0|cmd1")
    getCheckboxCmd: function (id) {
        var cb = $("#" + id);
        return cb.attr("cmdKey").split("|")[cb[0].checked ? 1 : 0];
    },
    //获得页面指令(页面可以未打开);
    //page:页面
    getPageCmds: function (page, onlyChanged) {
        let cmds = []; //最终结果
        let dumpKey, val;
        //所有dumpKey控件=>提取刷新值
        for (let elIndex = 0; elIndex < page.el.length; elIndex++) {
            //普通控件text/select/checkbox
            //有attrs，且其中有dumpKey的
            if (page.el[elIndex].attrs && page.el[elIndex].attrs.dumpKey) {
                let value = Device.getOneDumpValue(
                    page.el[elIndex].attrs.dumpKey,
                    page.el[elIndex].attrs.dumpParamIndex,
                    page.el[elIndex].attrs.transcode
                );
                if (page.el[elIndex].attrs.dealDumpParam) {
                    value = eval(page.el[elIndex].attrs.dealDumpParam);
                }
                page.el[elIndex].attrs.cmdVal = value;
            }
            //datagrid
            else if (page.dgData) {
                //行
                for (let row = 0; row < page.dgData.rows.length; row++) {
                    //列
                    for (let col = 0; col < page.dgData.columns.length; col++) {
                        dumpKey = page.dgData.columns[col].dumpKey; //dumpKey
                        // 存在dumpKey
                        if (dumpKey) {
                            //转换其中的序号
                            dumpKey = this.updateCmdNum2Index(dumpKey, row);
                            if (Device.dumpData.has(dumpKey)) {
                                //修改值为刷新取出的值
                                let value = Device.getOneDumpValue(
                                    dumpKey,
                                    page.dgData.columns[col].dumpParamIndex,
                                    page.dgData.columns[col].transcode
                                );
                                //有处理刷新指令的方法
                                if (page.dgData.columns[col].dealDumpParam) {
                                    value = eval(page.dgData.columns[col].dealDumpParam);
                                }
                                page.dgData.rows[row][page.dgData.columns[col].field] = value;
                            }
                        }
                    }
                }
            }
        }
        //生成指令(需要上面全部更新后才能生成，所以不能放在一个循环中)
        //所有cmdKey控件（普通控件，非datagrid控件）
        for (let elIndex = 0; elIndex < page.el.length; elIndex++) {
            //有attrs，并且其中有cmdKey的
            if (page.el[elIndex].attrs && page.el[elIndex].attrs.cmdKey) {
                //自定义了获得指令的方法
                if (page.el[elIndex].attrs.getValue) {
                    val = eval(page.el[elIndex].attrs.getValue);
                } else {
                    val = page.el[elIndex].attrs.cmdVal;
                    if (!defined(val) || val == null) {
                        val = "";
                    } else if (defined(page.el[elIndex].attrs.transcode)) {
                        val = Device.transCode(val);
                    }
                }
                cmds.push(page.el[elIndex].attrs.cmdKey + val);
            }
        }
        //datagrid
        if (page.dgData) {
            let rows = page.dgData.rows;
            //只获得更新了的行指令
            if (defined(onlyChanged) && onlyChanged) {
                rows = $("#" + page.id + "_dg").datagrid("getChanges");
            }
            let columns = page.dgData.columns;
            let cmdKey, val, val2; //值
            let transcode; //是否转码
            for (let col in columns) {
                //查找有cmdKey的列
                if (defined(columns[col].cmdKey)) {
                    for (let row in rows) {
                        //生成指令
                        cmdKey = columns[col].cmdKey.replace("<n>", rows[row].index); //替换指令头中的序号
                        val = rows[row][columns[col].field];
                        //需要转码
                        transcode = defined(columns[col].transcode);
                        if (transcode) {
                            val = Device.transCode(val);
                        }
                        //设置指令包括多个参数
                        if (defined(columns[col].otherFields)) {
                            val2 = "";
                            let otherFields = columns[col].otherFields.split(",");
                            //循环其它参数（注意：转码使用的同一个(cmdKey这一列的transcode)）
                            for (let fieldIndex in otherFields) {
                                val2 = rows[row][otherFields[fieldIndex]];
                                val2 = transcode ? Device.transCode(val2) : val2;
                                val += "," + val2;
                            }
                        }
                        //自定义了获得指令的方法
                        if (defined(columns[col].getValue)) {
                            let value = val; //下面getValue方法使用
                            val = eval(columns[col].getValue);
                        }
                        cmds.push(cmdKey + val); //获得行中的列的值，并放入保存的指令集
                    }
                }
            }
        }
        return cmds;
    },
    //保存所有页面指令
    saveAllPageCmd: function () {
        let cmds = ["STARTCMD"]; //用于快速执行指令(和COMMITCMD配套使用)
        //所有页面
        for (let i = 0; i < CmdPage.pages.length; i++) {
            cmds = cmds.concat(CmdPage.getPageCmds(CmdPage.pages[i]));
        }
        cmds.push("COMMITCMD");
        cmds.push("DUMPS"); //用于执行指令完成后自动刷新
        //转为字符串，并添加开始结束符
        let content = "";
        for (let i in cmds) {
            content += Device.addCmdHE(cmds[i]);
        }
        saveCmdsToFile(content);
    },
    //清空页面数据
    clearPageData: function (page) {
        //清空
        $("#{id} [dumpKey]".format(page)).each(function () {
            CmdPage.setElementValue(this, "");
        });
        //清空表格数据
        if (page.dgData) {
            for (let row = 0; row < page.dgData.rows.length; row++) {
                for (let key in page.dgData.rows[row]) {
                    if (key != "index") {
                        page.dgData.rows[row][key] = "";
                    }
                }
            }
            DatagridTool.updateData(page.id + "_dg");
        }
    },
};